﻿Imports System
Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports System.IO
Imports System.Xml.Serialization
Imports Microsoft.TeamFoundation.WorkItemTracking.Client

Public Class ItemCollection
    Inherits ObservableCollection(Of Item)
    Implements INotifyPropertyChanged

    Public Sub New()

    End Sub


    Private m_current As Item
    Private m_dirty As Boolean


    ''' <summary>
    ''' Item currently selected in application
    ''' </summary>
    Public Property Current() As Item
        Get
            Return m_current
        End Get
        Set(ByVal value As Item)
            If Not m_current Is value Then
                m_current = value
                OnPropertyChanged(New PropertyChangedEventArgs("Current"))
                OnCurrentChanged()
            End If
        End Set
    End Property

    ''' <summary>
    ''' Get or set if the list has been modified.
    ''' </summary>
    Public Property IsDirty() As Boolean
        Get
            Return m_dirty
        End Get
        Set(ByVal value As Boolean)
            m_dirty = value
        End Set
    End Property

    ''' <summary>
    ''' A Item or relationship was added, removed or modified in the list. This is used
    ''' instead of CollectionChanged since CollectionChanged can be raised before the 
    ''' relationships are setup (the Item was added to the list, but its Parents, Children,
    ''' Sibling and Spouse collections have not been established). This means the subscriber 
    ''' (the diagram control) will update before all of the information is available and 
    ''' relationships will not be displayed.
    ''' 
    ''' The ContentChanged event addresses this problem and allows the flexibility to
    ''' raise the event after *all* Items have been added to the list, and *all* of
    ''' their relationships have been established. 
    ''' 
    ''' Objects that add or remove Items from the list, or add or remove relationships
    ''' should call OnContentChanged when they want to notify subscribers that all
    ''' changes have been made.
    ''' </summary>
    Public Event ContentChanged As EventHandler(Of ContentChangedEventArgs)

    ''' <summary>
    ''' The details of a Item changed.
    ''' </summary>
    Public Sub OnContentChanged()
        m_dirty = True
        If Not ContentChangedEvent Is Nothing Then
            RaiseEvent ContentChanged(Me, New ContentChangedEventArgs(Nothing))
        End If
    End Sub

    ''' <summary>
    ''' The details of a Item changed, and a new Item was added to the collection.
    ''' </summary>
    Public Sub OnContentChanged(ByVal newItem As Item)
        m_dirty = True
        If Not ContentChangedEvent Is Nothing Then
            RaiseEvent ContentChanged(Me, New ContentChangedEventArgs(newItem))
        End If
    End Sub

    ''' <summary> 
    ''' The primary Item changed in the list.
    ''' </summary>
    Public Event CurrentChanged As EventHandler

    Protected Sub OnCurrentChanged()
        If Not CurrentChangedEvent Is Nothing Then
            RaiseEvent CurrentChanged(Me, EventArgs.Empty)
        End If
    End Sub

#Region " Add new Items / relationships "

    ''' <summary>
    ''' Adds Parent-Child relationship between Item and child with the provided parent-child relationship type.
    ''' </summary>
    Public Sub AddChild(ByVal Item As Item, ByVal child As Item)
        'add child relationship to Item
        Item.Relationships.Add(New ChildRelationship(child))

        'add Item as parent of child
        child.Relationships.Add(New ParentRelationship(Item))

        ' add the child to the main Items list
        If Not Me.Contains(Item) Then
            Me.Add(child)
        End If
    End Sub

    ''' <summary>
    ''' Adds sibling relation between the Item and the sibling
    ''' </summary>
    Public Sub AddSibling(ByVal Item As Item, ByVal sibling As Item)
        ' assign sibling to each other    
        Item.Relationships.Add(New SiblingRelationship(sibling))
        sibling.Relationships.Add(New SiblingRelationship(Item))

        ' add the sibling to the main Items list
        If Not Me.Contains(sibling) Then
            Me.Add(sibling)
        End If
    End Sub

    ''' <summary>
    ''' Adds sibling relation between the Item and the sibling
    ''' </summary>
    Public Sub AddWorkItem(ByVal Item As Item, ByVal wi As Item)
        ' assign sibling to each other    
        Item.Relationships.Add(New WIRelationship(wi))
        wi.Relationships.Add(New WIRelationship(Item))
        ' add the sibling to the main Items list
        If Not Me.Contains(wi) Then
            Me.Add(wi)
        End If
    End Sub

#End Region

    Public Function Find(ByVal id As String) As Item
        For Each Item As Item In Me
            If Item.Id = id Then
                Return Item
            End If
        Next
        Return Nothing
    End Function

End Class
